package com.jec.module.sysconfig.command;

import java.util.List;

import com.google.common.collect.Lists;
import com.jec.module.sysconfig.entity.RelayBusiness;
import com.jec.protocol.command.Command;
import com.jec.protocol.pdu.PDU;
import com.jec.protocol.pdu.PduConstants;
import com.jec.protocol.pdu.ProtocolUtils;
import com.jec.protocol.pdu.SNGenerator;
import com.jec.protocol.pdu.implement.IncreasedPduBuilder;
import com.jec.protocol.unit.BCD;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j;

/**
 * Created by jeremyliu on 9/26/16.
 */
@Log4j
public class RelayBusinessCommand extends Command {
	
	public static final int MAX_ENTRIES = 64;

	@Getter @Setter
    private RelayBusiness relayBusiness;

	@Getter @Setter
    private int mainSlot;

	@Getter @Setter
    private int netId;

    public RelayBusinessCommand(){

    }

    public RelayBusinessCommand(RelayBusiness relayBusiness, int mainSlot, int netId){
        this.relayBusiness = relayBusiness;
        this.mainSlot = mainSlot;
        this.netId = netId;
    }


    @Override
    public PDU buildRequestPdu() throws Exception {
    	
    	IncreasedPduBuilder builder = new IncreasedPduBuilder();
		builder.addInteger8(SNGenerator.nextSN());
		builder.addInteger8(PduConstants.CMD_TYPE_YWPZ);
		builder.addInteger8(PduConstants.CMD_CODE_SZCS);
		builder.addInteger8(relayBusiness.isDigital() ? 0x0C : 0x0F);
		builder.addInteger8(PduConstants.CARD_TYPE_MCB);
		builder.addInteger8(mainSlot);
	
		builder.addBCD(BCD.fromString(relayBusiness.getCode()), PduConstants.LENGTH_OF_BCD);
		

		List<Entry> entries = getEntris();
		
		builder.addInteger8(Math.min(entries.size(), MAX_ENTRIES));
		
		for(int i = 0; i < MAX_ENTRIES; i++) {
			if(i < entries.size()) {
				Entry entry = entries.get(i);
				builder.addInteger8(entry.slot);
				builder.addInteger16(entry.ts);
			} else {
				builder.addInteger8(0);
				builder.addInteger16(0);
			}
		}
		
		IncreasedPduBuilder head = new IncreasedPduBuilder();
		head.addInteger8(0);
		head.addInteger8(netId);
		head.addInteger8(PduConstants.ID_LOCAL);
		head.addInteger8(PduConstants.PROTOCOL_TYPE);
		head.addInteger16(builder.size());
		head.addBuilder(builder);

        return head.buildPdu();
    }

    @Override
    public void processResponsePdu(PDU pdu) throws Exception {
        if(ProtocolUtils.getCmdSN(pdu) != ProtocolUtils.getCmdSN(request)) {
            error("回应指令与请求指令序号不匹配");
        }


        int cmdCode = ProtocolUtils.getCmdCode(pdu);
        if(cmdCode == PduConstants.CMD_CODE_SZSB) { // 失败

            result = false;
            errorText = String.valueOf(pdu.getInt8(PduConstants.LENGTH_OF_HEAD + PduConstants.LENGTH_OF_BCD));

        } else if( cmdCode == PduConstants.CMD_CODE_SZCG) { // 成功

            result = true;


        } else {  // 命令字错误

            errorText = "回应指令命令字错误";

        }
    }
    
	class Entry {
		public int slot;
		public int ts;
	}
	
	private List<Entry> getEntris() {
		
		String entriesString = relayBusiness.getEntries();
		String[] entryStrings = entriesString.split("\n");
		
		List<Entry> list = Lists.newArrayList();
		
		for(String s : entryStrings) {
			
			try {
				
				String[] st = s.split(".");
				if(st.length == 2) {
					
					int slot = Integer.parseInt(st[0]);
					int ts = Integer.parseInt(st[1]);
					
					Entry entry = new Entry();
					entry.slot = slot;
					entry.ts = ts;
					
					list.add(entry);
					
				}
				
			} catch(Exception e) {
				log.error("Build entry failed.", e);
			}
			
		}
		
		return list;
		
	}
}
